iT邦幫忙

2023 iThome 鐵人賽

DAY 6
0
自我挑戰組

解三十天的 CodeWars系列 第 6

Pete, the baker

  • 分享至 

  • xImage
  •  

CodeWars 題目

Link

難度

5 kyu

題目

參數是兩個物件;分別是烤蛋糕需要的材料,以及現在擁有的材料。
計算能夠做出的最大蛋糕數量,不存在單位設定。

思路

必須確保都擁有所需材料,如果有任何一個材料不存在就直接返回 0。

可以從現有材料慢慢扣;
或用整除的方式,取得所有材料的最小商;即為答案。

pseudo code

for(let item of recipe)
  if(!available[item]) return 0

recipe.Object.keys()
array.map(item => Math.floor(available[item]/recipe[item])

return Math.min(...array)

實作

function cakes(recipe, available) {
   for (let item of Object.keys(recipe)) {
      if (!available[item]) return 0;
   }
   let array = Object.keys(recipe)
							 .map(item => Math.floor(available[item] / recipe[item]));
   return Math.min(...array);
}

// 可縮短成這樣,但可能不好閱讀
function cakes(recipe, available) {
   return Math.min(...Object.keys(recipe).map(item => {
      if (!available[item]) return 0;
      return Math.floor(available[item] / recipe[item]);
   }));
}

使用 Object.keys 將食譜物件的 key,也就是屬性名稱;用 for…of 迭代,一一去獲取食譜上所需的材料名稱。

如果在 available 現有材料物件中,無法取得食譜上的某材料,則代表不可能完成,返回 0。

map 產生新的陣列,計算現有材料除以對應的食譜材料數量,使用 Math.floor 返回整數的商;再從 Math.min 取得所有材料的最小值,也就是解答。

他人的解法

function cakes(recipe, available) {
  return Object.keys(recipe).reduce(function(val, ingredient) {
    return Math.min(Math.floor(available[ingredient] / recipe[ingredient] || 0), val)
  }, Infinity)  
}

Object.keys 將食譜物件的屬性名稱轉為陣列,使用陣列方法 reduce 迭代元素。

第二參數 Infinity 為初始值,代表正整數的無限大

第一參數 Function 中的 參數 val,代表累加值;第一次迭代會帶入 reduce 的第二參數;ingredient 表示迭代中的陣列元素。

Math.floor(available[ingredient] / recipe[ingredient] || 0)

取得現有原料除以食譜之後的商;如果不存在就返回 0。

Math.min(..., val)
上面得到的結果,與 val 比對取得最小值。

舉例:

// 食譜
let recipe = {
   flour: 500,
   sugar: 200,
   eggs: 1
};

// 現有材料
let available = {
   flour: 1200,
   sugar: 1200,
   eggs: 5,
   milk: 200
};

第一次的 reduce,val 為 Infinity、ingredient 為 flour
Math.floor(1200 / 500 || 0) 輸出為 2,Math.min(2, Infinity) 輸出為 2。

第二次的 reduce,val 為 2,ingredient 為 sugar
Math.floor(1200 / 200 || 0) 輸出為 6,Math.min(6, 2) 輸出為 2。

第二次的 reduce,val 為 2,ingredient 為 eggs
Math.floor(5 / 1 || 0) 輸出為 5,Math.min(5, 2) 輸出為 2。

recipe 迭代結束,reduce 結果為 2。

心得

在陣列方法中,reduce 算是我比較後期才學習的。
越解題越會感覺到原生方法的重要性。

不過最近觀察到,解題之後的討論常會講到「易讀性」。
在協同開發時,要怎麼與人配合?其中一點就是寫容易理解的程式碼。
不過容易理解 =/= 程式碼簡潔有力,很多過度的縮寫反而被人所詬病呢。


上一篇
The Hashtag Generator
下一篇
First non-repeating character
系列文
解三十天的 CodeWars30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言